package com.xianyv.util;


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/*
 * @Description:
 * @Author:
 * @CreateDate:     2022/10/29 23:23
 * @Param:
 * @Return:
 **/
public class JwtUtils {

    /**
     * 说明：需要修改的只有常量过期时间，以及 getJwtToken 方法参数（方法内的分类，头部信息）
     */

    // 常量
    public static final long EXPIRE = 1000 * 60 * 60 * 24;// tocket 过期时间
    public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";// 秘钥（每个企业有自己的加盐方式）
    public static final String TOKEN_NAME = "token";//header中token命名

    /**
     * 生成 token 字符串方法，参数为用户信息（当然可以是多个参数了）
     * @param id
     * @param nickname
     * @return
     */
    public static String getJwtToken(String id, String nickname){

        String JwtToken = Jwts.builder()
                // 1、设置头信息（固定，不需要改动）
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                // 2、设置过期时间
                .setSubject("guli-user")// 分类（可设置）
                .setIssuedAt(new Date())
                // 表示当前是时间加上 过期时间，如果超过了就过期了
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                // 3、设置token 主体部分（用户信息）
                .claim("id", id)
                .claim("nickname", nickname)
                // 4、防伪标识，秘钥2（和上面常量不是同一个）
                .signWith(SignatureAlgorithm.HS256, APP_SECRET)
                .compact();

        return JwtToken;
    }

    /**
     * 判断token是否存在与有效（通过秘钥判断）
     * @param jwtToken
     * @return
     */
    public static boolean checkToken(String jwtToken) {
        if(jwtToken == null || jwtToken.equals("")) return false;
        try {
            // 判读是否为同一个秘钥
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 判断token是否存在与有效（通过reqiest 头信息判断）
     * @param request
     * @return
     */
    public static boolean checkToken(HttpServletRequest request) {
        try {
            String jwtToken = getHeaderToken(request);
            if(jwtToken == null || jwtToken.equals("")) return false;
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static String getMemberValueByJwtToken(String token,String key) {
        String jwtToken = token;
        if(jwtToken == null || jwtToken.equals("")) return "";
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
        // Claims 上面入参的用户信息
        Claims claims = claimsJws.getBody();
//        System.out.println("claims body:" + claims);
        return (String)claims.get(key);
    }
    public static String getMemberValueByJwtToken(HttpServletRequest request,String key) {
        String jwtToken = getHeaderToken(request);
        return getMemberValueByJwtToken(jwtToken,key);
    }

    /**
     * 根据token获取用户id（当然也可获取name等等，看你设计的用户信息有什么）
     * @param request
     * @return
     */
    public static String getMemberIdByJwtToken(HttpServletRequest request) {
        return getMemberValueByJwtToken(request,"id");
    }

    public static String getHeaderToken(HttpServletRequest request){
        String jwtToken = request.getHeader(TOKEN_NAME);
        return jwtToken;
    }


//    //测试 JWT工具类
//    public static void main(String[] args) {
//
//        //JSON 字符串
//        String id = "9527";
//        String name = "刘亦菲";
//        String token = JwtUtils.getJwtToken(id, name);
//        System.out.println("获取token值: " + token);
//
//        //验证token 是否有效
//        boolean checkToken = JwtUtils.checkToken(token);
//        String result = checkToken == true?"有效":"无效";
//        System.out.println("token是否有效:" + result);
//
//        //解析token值, 获取id值
//        String value = JwtUtils.getMemberValueByJwtToken(token, "id");
//        System.out.println("解析token值:" + value);
//
//        //解析token值, 获取name值
//        value = JwtUtils.getMemberValueByJwtToken(token, "nickname");
//        System.out.println("解析token值:" + value);
//
//    }


}


